
package classes;


import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Vector;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
//import  sun.audio.*;    //import the sun.audio package
//import  java.io.*;



public class ReportsPanel extends JPanel{
    
    ReportGeneration reportController = new ReportGeneration();

    JLabel lblReportGeneration = new JLabel("Report Generation");
    
    Vector<String> Report1 = new Vector<String>();
    Vector<String> Report2 = new Vector<String>();
    Vector<String> Report3 = new Vector<String>();
    
    Vector<String> Header1 = new Vector<String>();
    Vector<String> Header2 = new Vector<String>();
    Vector<String> Header3 = new Vector<String>();
 
    
    DefaultTableModel dtm1;
    JTable Report = new JTable();
    DefaultTableModel dtm2;
    DefaultTableModel dtm3;
    JTable ReportPer = new JTable();
    
    JLabel lblReports = new JLabel("Report Type:");
    String[] Reports = {"Sales Report", "Services Report"};
    JComboBox selectReport = new JComboBox(Reports);
    
    JLabel lblDate = new JLabel("Date Range:");
    String Months[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
    int[] intDay = new int[31];
    String[] strDay = new String[31];
    int[] intYear = new int[30];
    String strYear[] = new String[30];
    JComboBox Month1 = new JComboBox(Months);
    JComboBox Day1 = new JComboBox();
    JComboBox Year1 = new JComboBox();
    
    JLabel lblTo = new JLabel("To");
    
    JComboBox Month2 = new JComboBox(Months);
    JComboBox Day2 = new JComboBox();
    JComboBox Year2 = new JComboBox();
    
    JScrollPane scrollPane = new JScrollPane(Report);
    
    JScrollPane scrollPane2 = new JScrollPane(ReportPer);
    
    JButton btnGenerate = new JButton("Generate", new ImageIcon(getClass().getResource("/images/sales-report.png")));
    JButton btnCancel = new JButton("Back", new ImageIcon(getClass().getResource("/images/cancel.png")));
    
    JLabel lblTotal = new JLabel("Total Sales:");
    JLabel lblTotalValue = new JLabel();

    JButton btnGenerateExcel = new JButton("Generate Excel File", new ImageIcon(getClass().getResource("/images/excel.png"))); 
//    
//    InputStream in;
//    AudioStream as;  
    
    public ReportsPanel()
    {
       
        //panel layout
        setLayout(null);
        setSize(740,655);
        setVisible(false);
        setOpaque(false);

        //add to panel
        add(lblReportGeneration);
        add(btnCancel);
        add(scrollPane);
        add(scrollPane2);
        add(btnGenerate);
        add(lblReports);
        add(selectReport);
        add(lblDate);
        add(Month1);
        add(Day1);
        add(Year1);
        add(Month2);
        add(Day2);
        add(Year2);
        add(lblTo);
        add(lblTotal);
        add(lblTotalValue);
        add(btnGenerateExcel);

        //set font
        lblReportGeneration.setFont(new Font("Century Gothic", Font.BOLD, 16));
        btnCancel.setFont(new Font("Century Gothic", Font.BOLD, 14));
        Report.setFont(new Font("Century Gothic", Font.PLAIN, 14));
        ReportPer.setFont(new Font("Century Gothic", Font.PLAIN, 14));
        btnGenerate.setFont(new Font("Century Gothic", Font.BOLD, 14));
        lblReports.setFont(new Font("Century Gothic", Font.BOLD, 14));
        selectReport.setFont(new Font("Century Gothic", Font.PLAIN, 14));
        lblDate.setFont(new Font("Century Gothic", Font.BOLD, 14));
        Month1.setFont(new Font("Century Gothic", Font.PLAIN, 14));
        Day1.setFont(new Font("Century Gothic", Font.PLAIN, 14));
        Year1.setFont(new Font("Century Gothic", Font.PLAIN, 14));
        Month2.setFont(new Font("Century Gothic", Font.PLAIN, 14));
        Day2.setFont(new Font("Century Gothic", Font.PLAIN, 14));
        Year2.setFont(new Font("Century Gothic", Font.PLAIN, 14));
        lblTo.setFont(new Font("Century Gothic", Font.BOLD, 14));
        lblTotal.setFont(new Font("Century Gothic", Font.BOLD, 14));
        lblTotalValue.setFont(new Font("Century Gothic", Font.BOLD, 14));
        btnGenerateExcel.setFont(new Font("Century Gothic", Font.BOLD, 14));
      
       //setBounds
         lblReportGeneration.setBounds(20,20,150,30);
         btnCancel.setBounds(595, 600, 105, 30);
         btnGenerate.setBounds(20, 600, 120, 30);
         btnGenerateExcel.setBounds(250, 600, 190, 30);
         scrollPane.setBounds(20,160,680,250);
         scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
         scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
         
         scrollPane2.setBounds(20,430,680,93);
         scrollPane2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
         scrollPane2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
         
         lblReports.setBounds(210,80, 250, 30);
         selectReport.setBounds(300,80, 150, 30);
         lblDate.setBounds(20, 120, 150, 30);
         Month1.setBounds(105,120,110,30);
         Day1.setBounds(220, 120, 50, 30);
         Year1.setBounds(275, 120, 80, 30);
         lblTo.setBounds(365,120,30,30);
         Month2.setBounds(390,120,110,30);
         Day2.setBounds(505, 120, 50, 30);
         Year2.setBounds(555, 120, 80, 30);
         lblTotal.setBounds(20, 530, 150, 30);
         lblTotalValue.setBounds(100, 530, 150, 30);
         InitializeDrop(new Integer(31) , "day1");
         InitializeDrop(new Integer(31) , "day2");
         InitializeYear();
     
         selectReport.addActionListener (new ActionListener () {
         public void actionPerformed(ActionEvent e) {
            if(selectReport.getSelectedIndex()==0) {
                 Report.setModel(new DefaultTableModel(null, new String[] {"Date", "Service Category", "Description", "Patient Name", "Price"}));
                 ReportPer.setModel(new DefaultTableModel(null, new String[] {"Dental Procedure", "Total Sales"}));
                 lblTotal.setText("Total Sales:");
                  lblTotalValue.setLocation(100,530);
                  lblTotalValue.setText(null);
            }
            else if (selectReport.getSelectedIndex()==1) {
                Report.setModel(new DefaultTableModel(null, new String[] {"Date", "Service Category", "Description", "Patient Name", "Price"})); 
                ReportPer.setModel(new DefaultTableModel(null, new String[] {"Dental Procedure", "Total Services"}));
                lblTotal.setText("Total Services:");
                lblTotalValue.setLocation(120,530);
                lblTotalValue.setText(null);
            }
        }
      });
         
          Month1.addActionListener(new ActionListener() {
             public void actionPerformed (ActionEvent e){
                 
                boolean leap = false;
                
                leap = CheckLeap(Integer.parseInt(Year1.getSelectedItem().toString()));
                
                if(Month1.getSelectedIndex() == 1)
                {
                    if(leap==false)
                        InitializeDrop(28, "day1");
                    else
                        InitializeDrop(29, "day1"); 
                }
                else if (Month1.getSelectedIndex() == 0 || Month1.getSelectedIndex() == 2 || Month1.getSelectedIndex() == 4 
                        || Month1.getSelectedIndex() == 6 || Month1.getSelectedIndex() == 7 || Month1.getSelectedIndex() == 9
                        || Month1.getSelectedIndex() == 11)
                    InitializeDrop(31, "day1");
                else if (Month1.getSelectedIndex() == 3 || Month1.getSelectedIndex() == 5 || Month1.getSelectedIndex() == 8
                        || Month1.getSelectedIndex() == 10)
                    InitializeDrop(30, "day1");
             }
         }
         );
          
          Month2.addActionListener(new ActionListener() {
             public void actionPerformed (ActionEvent e){
                 
                boolean leap = false;
                
                 leap = CheckLeap(Integer.parseInt(Year2.getSelectedItem().toString()));
                
                 if(Month2.getSelectedIndex() == 1)
                {
                    if(leap==false)
                        InitializeDrop(28, "day2");
                    else
                        InitializeDrop(29, "day2"); 
                }
                else if (Month2.getSelectedIndex() == 0 || Month2.getSelectedIndex() == 2 || Month2.getSelectedIndex() == 4 
                        || Month2.getSelectedIndex() == 6 || Month2.getSelectedIndex() == 7 || Month2.getSelectedIndex() == 9
                        || Month2.getSelectedIndex() == 11)
                    InitializeDrop(31, "day2");
                else if (Month2.getSelectedIndex() == 3 || Month2.getSelectedIndex() == 5 || Month2.getSelectedIndex() == 8
                        || Month2.getSelectedIndex() == 10)
                    InitializeDrop(30, "day2");                   
             }
         }
         );
          
          Year1.addActionListener(new ActionListener() {
             public void actionPerformed (ActionEvent e){
                 
                boolean leap = false;
                
                 leap = CheckLeap(Integer.parseInt(Year1.getSelectedItem().toString()));
                
                 if(Month1.getSelectedIndex() == 1)
                {
                    if(leap==false)
                        InitializeDrop(28, "day1");
                    else
                        InitializeDrop(29, "day1"); 
                }
             }
         }
         );
          
          Year2.addActionListener(new ActionListener() {
             public void actionPerformed (ActionEvent e){
                 
                boolean leap = false;
                
                 leap = CheckLeap(Integer.parseInt(Year2.getSelectedItem().toString()));
                
                 if(Month2.getSelectedIndex() == 1)
                {
                    if(leap==false)
                        InitializeDrop(28, "day2");
                    else
                        InitializeDrop(29, "day2"); 
                }
             }
         }
         );
          
          btnGenerate.addActionListener(new ActionListener() {
             public void actionPerformed (ActionEvent e){
                 
                 if(CheckDateRange() == false)
                 {
                     //playSound("error.wav");
                     JOptionPane.showMessageDialog(Main.frame.report,"Invalid date range.", "Error Message", JOptionPane.ERROR_MESSAGE);                    
                 } 
                 else
                 {
                     SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                     Calendar c1 = Calendar.getInstance();
                     Calendar c2 = Calendar.getInstance();
                     c1.set(Integer.parseInt(Year1.getSelectedItem().toString()), Month1.getSelectedIndex(), Day1.getSelectedIndex()+1);
                     c2.set(Integer.parseInt(Year2.getSelectedItem().toString()), Month2.getSelectedIndex(), Day2.getSelectedIndex()+1);               
                     setTable1(sdf.format(c1.getTime()),sdf.format(c2.getTime()));
                     boolean flag = true;
                     if(selectReport.getSelectedIndex()==0)
                         flag = true;           
                     else  if(selectReport.getSelectedIndex()==1)
                         flag=false;
                         
                     setTable2(sdf.format(c1.getTime()),sdf.format(c2.getTime()),flag);
                     if(dtm1.getDataVector().isEmpty() && dtm2.getDataVector().isEmpty())
                     {
                          //playSound("error.wav");
                          JOptionPane.showMessageDialog(Main.frame.report,"No records found between date range.", "Error Message", JOptionPane.ERROR_MESSAGE);
                     }
                }
             }
         }
         );
          
          btnGenerateExcel.addActionListener(new ActionListener() {
             public void actionPerformed (ActionEvent e){
                      boolean flag = true;
                     if(selectReport.getSelectedIndex()==0)
                         flag = true;           
                     else  if(selectReport.getSelectedIndex()==1)
                         flag=false;
                     try{
                      if(dtm1.getDataVector().isEmpty() == false && dtm2.getDataVector().isEmpty() == false)
                     {
                         int response = JOptionPane.showConfirmDialog(Main.frame.report, "Do you want to generate an excel file for this report?", "Confirm",
                         JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
                         if (response == JOptionPane.YES_OPTION)
                         {
                            reportController.GenerateExcelReport(dtm1,dtm2,lblTotalValue.getText(),flag);
                         }
                     }
                      else
                      {
                             //playSound("error.wav");
                             JOptionPane.showMessageDialog(Main.frame.report,"Please generate a report that is not empty first.", "Error Message", JOptionPane.ERROR_MESSAGE); 
                             
                      }
                    }
                     catch(NullPointerException a)
                     {
                         //playSound("error.wav");
                         JOptionPane.showMessageDialog(Main.frame.report,"Please generate a report that is not empty first.", "Error Message", JOptionPane.ERROR_MESSAGE);  
                     }
             }  
         }
         );
         
          
          Header1.add("Date");
          Header1.add("Service Category");
          Header1.add("Description");
          Header1.add("Patient Name");
          Header1.add("Price");

          Header2.add("Dental Procedure");
          Header2.add("Total Sales");

          Header3.add("Dental Procedure");
          Header3.add("Total Services");
          
          Report.setModel(new DefaultTableModel(null,new String[] {"Date", "Service Category", "Description"
          ,"Patient Name", "Price" }));
          ReportPer.setModel(new DefaultTableModel(null, new String[] {"Dental Procedure", "Total Sales"}));
          Report.setAutoCreateRowSorter(true);
          ReportPer.setAutoCreateRowSorter(true);
    }
    
//    private void playSound(String file)
//    {
//        try {
//            in = new FileInputStream(getClass().getResource("/sounds/" + file).getFile());
//            as = new AudioStream(in);
//        }
//        catch(Exception a)
//        {
//            a.printStackTrace();
//        }   
//     AudioPlayer.player.start(as);
//    }
    
   public void resetComponents()
   {
       selectReport.setSelectedIndex(0);
       lblTotalValue.setText(null);
       Day1.setSelectedIndex(0);
       Day2.setSelectedIndex(0);
       Month1.setSelectedIndex(0);
       Month2.setSelectedIndex(0);
       Year1.setSelectedIndex(0);
       Year2.setSelectedIndex(0);
   }
    
      private JTable autoResizeColWidth(JTable table, DefaultTableModel model) {
        table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
        table.setModel(model);

        int margin = 5;

        for (int i = 0; i < table.getColumnCount()-1; i++) {
            int                     vColIndex = i;
            DefaultTableColumnModel colModel  = (DefaultTableColumnModel) table.getColumnModel();
            TableColumn             col       = colModel.getColumn(vColIndex);
            int                     width     = 0;

            // Get width of column header
            TableCellRenderer renderer = col.getHeaderRenderer();

            if (renderer == null) {
                renderer = table.getTableHeader().getDefaultRenderer();
            }

            Component comp = renderer.getTableCellRendererComponent(table, col.getHeaderValue(), false, false, 0, 0);

            width = comp.getPreferredSize().width;

            // Get maximum width of column data
            for (int r = 0; r < table.getRowCount(); r++) {
                renderer = table.getCellRenderer(r, vColIndex);
                comp     = renderer.getTableCellRendererComponent(table, table.getValueAt(r, vColIndex), false, false,
                        r, vColIndex);
                width = Math.max(width, comp.getPreferredSize().width);
            }

            // Add margin
            width += 2 * margin;

            // Set the width
            col.setPreferredWidth(width);
        }

        ((DefaultTableCellRenderer) table.getTableHeader().getDefaultRenderer()).setHorizontalAlignment(
            SwingConstants.LEFT);

        // table.setAutoCreateRowSorter(true);
        table.getTableHeader().setReorderingAllowed(false);

        return table;
    }
    
    private void setTable1(String date1, String date2) {
        Report1 = reportController.ViewReport(date1,date2);
       
        dtm1 = new DefaultTableModel(Report1, Header1)
                {
            @Override
                    public boolean isCellEditable(int row, int col)
                    {
                        return false;
                    }
                };
        
        
        Report.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
        Report.setModel(dtm1);
        autoResizeColWidth(Report, dtm1);

        
    }
    
     private void setTable2(String date1, String date2, boolean flag) {
        Report2 = reportController.ViewReportPer(date1, date2, flag);
        String sum = new String();
         sum = reportController.GetTotal(date1,date2,flag);
        if(flag == true)
        {
        dtm2 = new DefaultTableModel(Report2, Header2)
                {
            @Override
                    public boolean isCellEditable(int row, int col)
                    {
                        return false;
                    }
                };
        }
        else if (flag == false) {
            dtm2 = new DefaultTableModel(Report2, Header3)
                {
            @Override
                    public boolean isCellEditable(int row, int col)
                    {
                        return false;
                    }
                };
        }
        
        ReportPer.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
        ReportPer.setModel(dtm2);
         if(sum!=null && flag == true)
            lblTotalValue.setText("P" + sum);
         else
            lblTotalValue.setText(sum);
            }
    
    private boolean CheckDateRange()
    {
        if((Year2.getSelectedIndex()- Year1.getSelectedIndex()) > 0)
        {
            return true;
        }
        else if ((Year2.getSelectedIndex()- Year1.getSelectedIndex()) == 0){
            if((Month2.getSelectedIndex()- Month1.getSelectedIndex()) > 0 )
            {
               return true;
            }
            else if((Month2.getSelectedIndex()- Month1.getSelectedIndex()) == 0) {
              if((Day2.getSelectedIndex()- Day1.getSelectedIndex()) >= 0)
                {
                    return true;
                }
            }
        }
        
         return false;  
    }
    
    
    private void InitializeDrop(int ctr, String day) {
        if(day.equals("day1"))
        {
        Day1.removeAllItems();
        
         for(int a = 1; a <= ctr; a++ )
            {     
                intDay[a-1] = a;
                strDay[a-1] = Integer.toString(intDay[a-1]);
                Day1.addItem(strDay[a-1]);
            }
         Day1.repaint();
        }
        else if(day.equals("day2"))
        {
         Day2.removeAllItems();
        
         for(int a = 1; a <= ctr; a++ )
            {     
                intDay[a-1] = a;
                strDay[a-1] = Integer.toString(intDay[a-1]);
                Day2.addItem(strDay[a-1]);
            }
         Day2.repaint();
        }
            
    }
    
    private void InitializeYear() {
         for(int a = 2011; a <= 2031; a++)
            {     
                int index = 0;
                intYear[index] = a;
                strYear[index] = Integer.toString(intYear[index]);
                Year1.addItem(strYear[index]);
                Year2.addItem(strYear[index]);
                index++;
            }
    }
    
    private boolean CheckLeap(int year) {
        if(year%4 == 0)
        {
            if(year%100 != 0)
            {
                return true;
            }
            else
            {
                if(year%400 == 0)
                    return true;
                else
                    return false;
            }
        }
        return false;
        }

}
